<template>
  <div class="flex-column a_c page">
    <div style="position: absolute; top: 120px; left: 0;">
      <el-button @click="btnClear">清空记录</el-button>
    </div>
    <div class="flex-column a_c ai-container" ref="aiContentRef">
      <div class="ai-content" >
        <div v-for="(item, index) in messageList" :key="index">
          <div class="flex-row j_e" v-if="item.role === 0">
            <div class="flex-row j_e my-talk-view">
              <div class="my-content">
                <v-md-preview :text="item.content"></v-md-preview>
              </div>
            </div>
          </div>
          <div class="ai-talk-container" v-if="item.role === 1">
            <div class="flex-column ai-talk-view">
              <v-md-preview :text="item.content" style="white-space: pre-line;"></v-md-preview>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="flex-row j_c input-container">
      <div class="flex-row a_c input-view">
        <el-input placeholder="请输入内容" @keyup.enter="btnSend" v-model="questionText"></el-input>
        <el-button class="btn-send" @click="btnSend" :loading="btnLoading" :disabled="btnLoading">
          <img src="@/assets/send_msg.png">
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, getCurrentInstance,onUnmounted } from 'vue';
import {ElMessage} from "element-plus";
import { emitter } from '@/utils/bus.js'
import {getIa, getUsedAbilityRecord, reqIaChat, reqChatList, clearChat} from "@/api/base";
import {useUserStore} from '@/pinia/modules/user'
import {useDataStore} from "@/pinia/modules/data";

const { proxy } = getCurrentInstance()
const userStore = useUserStore()
const dataStore = useDataStore()

const messageList = ref([])
const questionText = ref('')
const isStream = ref(false)
const incrementalFlag = ref(false)
const endFlag = ref(false)
const resMesData = ref('')
const isShowText = ref(false)
const showInTerVal = ref(null)
const resultText = ref('')
const btnLoading = ref(false)
const iaInfo = ref(null)

const aiContentRef = ref(null)

const handleVisibilityChange = () => {
  if (!document.hidden) {
    // tab重新可见时的逻辑
    let id = window.localStorage.getItem('recordId')
    if (id) {
      getUsedAbility(id)
    }
  }
}

onMounted(() => {
  document.addEventListener('visibilitychange', handleVisibilityChange);
})

const getUsedAbility = async (id) => {
  if (id) {
    const result = await getUsedAbilityRecord(id)
    questionText.value = result.text
    window.localStorage.setItem('recordId', '')
    btnSend()
  }
}

const initView = async () => {
  const data = await getIa()
  iaInfo.value = data
  messageList.value.push({
    role: 1,
    content: data.prologue
  })
  const record = await reqChatList()
  if (record) {
    record.forEach(item => {
      messageList.value.push({
        role: 0,
        content: item.prompt
      })
      messageList.value.push({
        role: 1,
        content: item.text
      })
    })
  }
  setTimeout(() => {
    autoScroll()
  }, 100)
}


initView()

const autoScroll = () => {
  aiContentRef.value.scrollTop = aiContentRef.value.scrollHeight
}

const btnSend = () => {
  if (!questionText.value) {
    ElMessage.error('请输入内容')
    return
  }
  startWrite()
}

const startWrite = () => {
  emitter.on('connect', wsConnect)
  emitter.on('getWsMessage', getMessage)
  proxy.$webSocket.connect(userStore.userInfo.userId)
}

/**
 * socket 链接成功
 */
const wsConnect = () => {
  // 调用请求数据接口
  iaChat()
}

const iaChat = async () => {
  messageList.value.push({
    role: 0,
    content: questionText.value
  })
  let data = {
    intelligentAgentId: iaInfo.value.id,
    prompt: questionText.value,
    sk: userStore.userInfo.userId
  }
  questionText.value = ''
  isShowText.value = true
  btnLoading.value = true
  isStream.value = true
  endFlag.value = false
  resMesData.value = ''
  resultText.value = ''
  autoScroll()
  const result = await reqIaChat(data)
  resultText.value = result.text
}

/**
 * 接受到 socket 数据
 */
const getMessage = (resp) => {
  // 处理 socket 数据
  if (resp.data === 'SK_NOT_EXIST_ERROR') {
    // this.getAiSkCode();
    return;
  } else if (resp.data === 'SOCKET_CHAT_ERROR') {
    // this.getAiSkCode();
    return;
  } else if (resp.data !== 'SK_NOT_EXIST_ERROR') {
    if (resp.data === 'INCREMENTAL_TRUE') {
      // 增量
      incrementalFlag.value = true
      return
    } else if (resp.data === 'INCREMENTAL_FALSE') {
      // 全量
      incrementalFlag.value = false
      return
    } else if (resp.data === 'WRITE_FINISH') {
      // 写作完成
      endFlag.value = true
      return
    } else {
      resMesData.value += resp.data
      if (isShowText.value) {
        showTextFun()
      }
    }
  }
}

const showTextFun = () => {
  if (!resMesData.value) return
  if (resMesData.value.length === 0) return
  isShowText.value = false
  var i = 0
  showInTerVal.value = setInterval(() => {
    if (i <= resMesData.value.length) {
      var text = resMesData.value.substring(0, i)
      i++
      if (messageList.value[messageList.value.length - 1].role !== 1) {
        messageList.value.push({
          role: 1,
          content: ''
        })
      }
      messageList.value[messageList.value.length - 1].content = text
      autoScroll()
    }
    if (endFlag.value && resultText.value.length === resMesData.value.length) {
      if (messageList.value[messageList.value.length - 1].content.length === resMesData.value.length) {
        closeConnect()
        isStream.value = false
        btnLoading.value = false
        isShowText.value = false
      }
    }
  }, 20)
}

const btnClear = async () => {
  await clearChat()
  messageList.value = []
  initView()
}

const closeConnect = () => {
  emitter.off('connect', wsConnect)
  emitter.off('getWsMessage', getMessage)
  proxy.$webSocket.close()
  clearInterval(showInTerVal.value)
}

onUnmounted(() => {
  document.removeEventListener('visibilitychange', handleVisibilityChange);
})

</script>

<style lang="scss" scoped>
  .page {
    background: linear-gradient(0deg, #F0F1F5 0%, #E9E8F9 100%);
    padding: 0;
    margin-bottom: 0;
    .ai-container {
      height: 75vh;
      width: 60%;
      overflow-y: scroll;
      .ai-content {
        margin-top: 30px;
        width: 90%;
      }
      .my-talk-view {
        margin: 20px 0;
        width: 80%;
        .my-content {
          background: #FFFFFF;
          border-radius: 10px;
          .github-markdown-body {
            padding: 0;
          }
        }
      }
      .ai-talk-container {
        margin: 20px 0;
        width: 80%;
        .ai-talk-view {
          background: #FFFFFF;
          border-radius: 10px;
        }
      }
    }



    .input-container {
      width: 100%;
      padding: 10px 0 50px 0;
      background: #E9E8F9;
      position: relative;

      .input-view {
        min-width: 60%;
        background: #FFFFFF;
        border-radius: 44px;
        margin: 0 20px;
        padding: 6px 0;
        .el-input {
          flex: 1;
          margin-left: 10px;
          padding: 10px;
          --el-input-text-color: #BEBDD1;
          --el-input-bg-color: transparent;
          --el-input-border: transparent;
          --el-input-border-color: transparent;
          --el-input-focus-border-color: transparent;
          --el-input-hover-border-color: transparent;
          --el-input-height: 50px;
        }
      }

      .btn-send {
        --el-button-hover-text-color: transparent;
        --el-button-border-color: transparent;
        --el-button-hover-bg-color: transparent;
        --el-button-outline-color: transparent;
        --el-button-active-border-color: transparent;
        --el-button-hover-border-color: transparent;
        height: 58px;
        background: transparent;
        margin-right: 20px !important;
        img {
          width: 58px;
          height: 58px;
          cursor: pointer;
        }
      }
    }
  }
</style>
